package iface.aplicativo.negocio.aps;

import iface.aplicativo.excecao.MensagemException;
import iface.aplicativo.integracao.dao.AcessorioDAO;
import iface.aplicativo.integracao.dao.CambioDAO;
import iface.aplicativo.integracao.dao.CombustivelDAO;
import iface.aplicativo.integracao.dao.FabricanteDAO;
import iface.aplicativo.integracao.dao.ModeloDAO;
import iface.aplicativo.integracao.dao.VeiculoDAO;
import iface.aplicativo.negocio.entidade.Acessorio;
import iface.aplicativo.negocio.entidade.Fabricante;
import iface.aplicativo.negocio.entidade.Modelo;
import iface.aplicativo.negocio.entidade.Veiculo;
import iface.aplicativo.negocio.enumerador.UfEnum;
import iface.aplicativo.util.Constantes;
import iface.aplicativo.util.ResourceMessageFactory;
import iface.aplicativo.util.UtilResource;
import iface.arquitetura.comum.string.UtilString;
import iface.arquitetura.utilitario.ListaTO;
import iface.arquitetura.utilitario.ListaUtil;
import iface.arquitetura.utilitario.ResourceMessageAnnotation;

import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.Hibernate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional(readOnly = true, rollbackFor = { Exception.class })
public class ManterVeiculosAPS {

	@ResourceMessageAnnotation(propertiesFile = { Constantes.RECURSO_MENSAGENS })
	private UtilResource resource = ResourceMessageFactory.inicialize(this);

	@Resource
	VeiculoDAO veiculoDAO;
	@Resource
	FabricanteDAO fabricanteDAO;
	@Resource
	ModeloDAO modeloDAO;
	@Resource
	CombustivelDAO combustivelDAO;
	@Resource
	CambioDAO cambioDAO;
	@Resource
	AcessorioDAO acessorioDAO;

	@Transactional(propagation = Propagation.REQUIRED)
	public String salvarVeiculo(Veiculo entidade) throws Exception {
		this.validarCamposVeiculo(entidade);
		this.validarExistencia(entidade);

		if (entidade.getCombustivel() != null
				&& entidade.getCombustivel().getId() == null) {
			entidade.setCombustivel(null);
		}
		if (entidade.getCambio() != null
				&& entidade.getCambio().getId() == null) {
			entidade.setCambio(null);
		}

		entidade.setAcessorios((List<Acessorio>) this.acessorioDAO
				.consultarAcessoriosPorIds(entidade.getAcessoriosAux()));

		if (entidade.getIdVeiculo() == null) {
			this.veiculoDAO.inserir(entidade);
			return this.resource.getMensagens("MSG01");
		} else {
			this.veiculoDAO.alterar(entidade);
			return this.resource.getMensagens("MSG02");
		}
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public String excluirVeiculo(Veiculo entidade) throws Exception {
		try {
			this.veiculoDAO.remover(entidade);
		} catch (Exception ex) {
			throw new Exception(ex);
		}
		return this.resource.getMensagens("MSG03");
	}

	public void validarCamposVeiculo(Veiculo entidade) throws Exception {
		this.resource.clearMensagens();

		if (entidade != null) {
			if (UtilString.isVazio(entidade.getNrPlaca())) {
				this.resource.addMensagens("MSG05", "Placa");
			}
			if (entidade.getFabricante() == null
					|| entidade.getFabricante().getId() == null) {
				this.resource.addMensagens("MSG05", "Fabricante");
			}
			if (entidade.getModelo() == null
					|| entidade.getModelo().getId() == null) {
				this.resource.addMensagens("MSG05", "Modelo");
			}
		}

		if (this.resource.isMensagens()) {
			throw new MensagemException(this.resource.getMensagens());
		}
	}

	public void validarExistencia(Veiculo entidade) throws Exception {
		this.resource.clearMensagens();

		Veiculo veiculoConsulta = this.veiculoDAO
				.consultarVeiculoPorPlaca(entidade.getNrPlaca());

		if (veiculoConsulta != null) {
			this.veiculoDAO.getHibernateTemplate().clear();
			if (entidade.getIdVeiculo() != null) {
				if (!veiculoConsulta.getIdVeiculo().equals(
						entidade.getIdVeiculo())) {
					this.resource.addMensagens("MSG11");
				}
			} else {
				this.resource.addMensagens("MSG11");
			}
		}

		veiculoConsulta = null;

		if (this.resource.isMensagens()) {
			throw new MensagemException(this.resource.getMensagens());
		}
	}

	public Veiculo consultarVeiculoPorPlaca(String nrPlaca) throws Exception {
		Veiculo entidade = null;
		try {
			entidade = this.veiculoDAO.consultarVeiculoPorPlaca(nrPlaca);
		} catch (Exception ex) {
			throw new Exception(ex);
		}
		return entidade;
	}

	public Collection<Veiculo> getTodosVeiculos() {
		Collection<Veiculo> veiculos = this.veiculoDAO.consultar();
		for (Veiculo veiculo : veiculos) {
			Hibernate.initialize(veiculo.getAcessorios());
		}
		return veiculos;
	}

	public Collection<ListaTO> consultarTodosFabricantes() {
		final List<ListaTO> lista = ListaUtil.listaBean2Lista(
				this.fabricanteDAO.consultar(), "id", "nmFabricante");

		return lista;
	}

	public Collection<ListaTO> consultarTodosCombustiveis() {
		final List<ListaTO> lista = ListaUtil.listaBean2Lista(
				this.combustivelDAO.consultar(), "id", "nmCombustivel");

		return lista;
	}

	public Collection<ListaTO> consultarTodosCambios() {
		final List<ListaTO> lista = ListaUtil.listaBean2Lista(
				this.cambioDAO.consultar(), "id", "nmCambio");

		return lista;
	}

	public Collection<ListaTO> consultarModelosPorFabricante(
			final Fabricante fabricante) {
		Collection<Modelo> modelos = new ArrayList<Modelo>();
		if (fabricante != null && fabricante.getId() != null) {
			modelos = this.modeloDAO.consultarModelosPorFabricante(fabricante);
		}

		return ListaUtil.listaBean2Lista(modelos, "id", "nmModelo");
	}

	public Collection<ListaTO> consultarTodasUfs() {
		EnumSet<UfEnum> ufs = EnumSet.allOf(UfEnum.class);
		Iterator<UfEnum> it = ufs.iterator();

		Collection<ListaTO> listaTO = new ArrayList<ListaTO>();
		ListaTO listaTOaux = new ListaTO("", ":: Selecione ::");
		listaTO.add(listaTOaux);

		while (it.hasNext()) {
			ListaTO item = new ListaTO();
			UfEnum e = it.next();
			item.setValue(e.name());
			item.setLabel(e.name());
			listaTO.add(item);
		}

		return listaTO;
	}

	public Collection<Acessorio> consultarTodosAcessorios() throws Exception {
		return this.acessorioDAO.consultar();
	}

}
